package com.learning.mybatis.plugin.interceptor.init.plugin;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;

import java.sql.Connection;
import java.util.Properties;

/**
 * ClassName: CustomPlugin
 * Description: 插件的使用必须要实现 Interceptor 接口
 * Date: 2020/8/14 15:20 【需求编号】
 *
 * @author Sam Sho
 * @version V1.0.0
 */
@Slf4j
@Intercepts({@Signature(type = Executor.class, method = "commit", args = {boolean.class})})
public class CustomPlugin implements Interceptor {

    /**
     * 直接覆盖所拦截对象原有的方法，因此他是差劲啊的核心方法
     * 通过 invocation 对象可以反射调度原来对象的方法
     *
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        log.info("~~~~~~~~~intercept~~~~~~~~~~~~");
        return invocation.proceed();
    }

    /**
     * target 是拦截对象，他的作用是给被拦截对象生成一个代理对象，并返回。
     * MyBatis 专门有一个工具类 Plugin ，用于这边使用生成代理对象，即四大对象实际是 Plugin 对象的代理。
     * 访问四大对象的方法，需要访问这个代理对象Plugin的 invoke 方法。在这个方法中，实现额前置调用插件拦截方法 Interceptor.intercept()
     *
     * @param target
     * @return
     */
    @Override
    public Object plugin(Object target) {
        log.info("~~~~~~~~~plugin~~~~~~~~~~~~");
        return Plugin.wrap(target, this);
    }

    /**
     * 允许在插件元素中配置所需参数，方法在插件初始化的时候被调用一次，然后把插件对象存入配置中
     *
     * @param properties
     */
    @Override
    public void setProperties(Properties properties) {
        log.info("~~~~~~~~~setProperties~~~~~~~~~~~~");
        Object name = properties.get("name");
        log.info("~~~~~~~~~获取 name 参数 {}~~~~~~~~~~~~", name);
    }
}
